/*
 * $Id: BufferPool.h,v 1.1 2005-04-18 11:28:07 bacon Exp $
 */

#ifndef _XPP_BAS_BUFFERPOOL_CLASS_
#define _XPP_BAS_BUFFERPOOL_CLASS_

#include <xp/types.h>
#include <xp/macros.h>
#include <xpp/Uncopyable.h>

//
// TODO: yet to be improved a lot
//

namespace xpp
{
	namespace bas
	{

		class BufferPool: public Uncopyable
		{
		public:
			enum {
				DFL_BLOCK_SIZE = 100000,
				MIN_BLOCK_SIZE = 10000
			};

			BufferPool (xp_size_t blockSize = DFL_BLOCK_SIZE);
			~BufferPool ();

			void* allocate (xp_size_t size);
			void  dispose (void* ptr);
			void  dispose ();

			xp_size_t blockSize () const
			{
				return block_size;
			}

			void setBlockSize (xp_size_t size)
			{
				if (size < MIN_BLOCK_SIZE) size = MIN_BLOCK_SIZE;
				block_size = size;
			}

		protected:
			struct Block;

			struct Chain {
				// header
				xp_size_t size;
				Block* owner;
				// body
				Chain* next;
			};

			struct Block {
				Chain* free;
				Block* next;
				Block* end;
				//xp_byte_t data[0];
			};

			Block* blocks;
			xp_size_t block_size;

			void* allocate (Block* block, xp_size_t size);
			Block* add_block (xp_size_t size);
		};

	}
}

#endif
